class map extends ui.mapUI {

    score: number;
    firstTouch: any = { x: 0, y: 0 };  //触摸按下位置
    lastTouch: any = { x: 0, y: 0 };    //触摸抬起位置
    mouseUp: boolean;   //鼠标是否已抬起
    /**
     * 地图字典
     * @type {{ [key: number]: number; }}
     * @memberof map
     */
    dicBuild: { [key: number]: number; }
    initPos: number[];
    bodyValue: number;
    diceNumber: number;
    gameover: boolean;
    constructor() {
        super();
        Laya.stage.addChild(this);
        this.init();
        Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.mouseHandler);
        Laya.stage.on(Laya.Event.MOUSE_UP, this, this.mouseHandler);
        // Laya.stage.on(Laya.Event.MOUSE_MOVE,this, this.mouseMove);

    }

    mouseMove(e: Laya.Event){
        console.log(e.stageX,e.stageY);
    }

    /**
     * 鼠标事件
     * 
     * @memberof map
     */
    mouseHandler(e: Laya.Event) {
        if (this.gameover) {
            alert("游戏已结束");
            return;
        }
        if (this.bodyValue <= 0) {

            alert("体力不足");
            return;
        }
        switch (e.type) {
            case Laya.Event.MOUSE_DOWN:
                this.firstTouch.x = e.stageX;
                this.firstTouch.y = e.stageY;
                break;
            case Laya.Event.MOUSE_UP:
                this.lastTouch.x = e.stageX;
                this.lastTouch.y = e.stageY;
                this.mouseUp = true;
                break;
        }
        if (this.mouseUp) {
            if (this.firstTouch.x != 0 && this.firstTouch.y != 0 && this.lastTouch.x != 0, this.lastTouch.y != 0) {
                if (this.lastTouch.x < this.firstTouch.x && this.lastTouch.y < this.firstTouch.y) {
                    this.update(Move.RightDownToLeftUp);
                } else if (this.lastTouch.x > this.firstTouch.x && this.lastTouch.y < this.firstTouch.y) {
                    this.update(Move.LeftDownToRightUp);
                } else if (this.lastTouch.x > this.firstTouch.x && this.lastTouch.y > this.firstTouch.y) {
                    this.update(Move.LeftUpToRightDown);
                } else if (this.lastTouch.x < this.firstTouch.x && this.lastTouch.y > this.firstTouch.y) {
                    this.update(Move.RightUpToLeftDown);
                }
            }
        }

    }
    /**
     * 更新位置 增加分数
     * 如果某个方向无法合并 那就无法向这个方向移动
     * 随机生成一个新的初级建筑 级别为1
     * 判断游戏结束
     *              1  
     *          5       2  
     *      9       6       3
     *  13      10      7       4
     *      14      11      8 
     *          15      12    
     *              16
     * @param {Move} move 
     * @memberof map
     */
    update(move: Move) {
        switch (move) {
            case Move.LeftDownToRightUp:
                //  *              1  
                //  *          5       2  
                //  *      9       6       3
                //  *  13      10      7       4
                //  *      14      11      8 
                //  *          15      12    
                //  *              16
                //循环的目的是消除建筑之间的空白地带  把建筑变紧凑
                for (let num = 13; num <= 16; num++) {  //横向
                    //纵向
                    for (let i = num - 8; i <= num; i += 4) {
                        for (let j = num - 12; j <= num - 4; j += 4) {
                            if (this.dicBuild[j] == 0 && this.dicBuild[i] != 0) {
                                this.dicBuild[j] = this.dicBuild[i];
                                this.dicBuild[i] = 0;
                                this.singlePosRender(i, this.dicBuild[j], j);
                            }
                        }
                    }
                    // if (this.dicBuild[num - 12] != 0 && this.dicBuild[num - 12] == this.dicBuild[num - 8]) {
                    //     this.dicBuild[num - 12]++;
                    //     this.dicBuild[num - 8] = 0;

                    // } if (this.dicBuild[num - 8] != 0 && this.dicBuild[num - 8] == this.dicBuild[num - 4]) {
                    //     this.dicBuild[num - 8]++;
                    //     this.dicBuild[num - 4] = 0;

                    // } if (this.dicBuild[num - 4] != 0 && this.dicBuild[num - 4] == this.dicBuild[num]) {
                    //     this.dicBuild[num - 4]++;
                    //     this.dicBuild[num] = 0;

                    // }

                }

                break;
            case Move.LeftUpToRightDown:
                //  *              1  
                //  *          5       2  
                //  *      9       6       3
                //  *  13      10      7       4
                //  *      14      11      8 
                //  *          15      12    
                //  *              16
                //1                 //1 2 3         /1
                //循环的目的是消除建筑之间的空白地带  把建筑变紧凑
                for (let num = 1; num <= 13; num += 4) {  //横向
                    //纵向
                    for (let i = num + 2; i >= num; i--) {
                        for (let j = num + 3; j >= num + 1; j--) {
                            if (this.dicBuild[j] == 0 && this.dicBuild[i] != 0) {
                                this.dicBuild[j] = this.dicBuild[i];
                                this.dicBuild[i] = 0;
                                this.singlePosRender(i, this.dicBuild[j], j);
                            }
                        }
                    }
                    // if (this.dicBuild[num + 3] != 0 && this.dicBuild[num + 3] == this.dicBuild[num + 2]) {
                    //     this.dicBuild[num + 3]++;
                    //     this.dicBuild[num + 2] = 0;

                    // } if (this.dicBuild[num + 2] != 0 && this.dicBuild[num + 2] == this.dicBuild[num + 1]) {
                    //     this.dicBuild[num + 2]++;
                    //     this.dicBuild[num + 1] = 0;

                    // } if (this.dicBuild[num + 1] != 0 && this.dicBuild[num + 1] == this.dicBuild[num]) {
                    //     this.dicBuild[num + 1]++;
                    //     this.dicBuild[num] = 0;

                    // }

                }
                break;
            case Move.RightDownToLeftUp:
                //  *              1  
                //  *          5       2  
                //  *      9       6       3
                //  *  13      10      7       4
                //  *      14      11      8 
                //  *          15      12    
                //  *              16

                for (let num = 4; num <= 16; num += 4) {  //横向
                    //纵向//循环的目的是消除建筑之间的空白地带  把建筑变紧凑
                    for (let i = num - 2; i <= num; i++) {
                        for (let j = num - 3; j <= num - 1; j++) {
                            if (this.dicBuild[j] == 0 && this.dicBuild[i] != 0) {
                                this.dicBuild[j] = this.dicBuild[i];
                                this.dicBuild[i] = 0;
                                this.singlePosRender(i, this.dicBuild[j], j);
                            }
                        }
                    }
                    // if (this.dicBuild[num - 3] != 0 && this.dicBuild[num - 3] == this.dicBuild[num - 2]) {
                    //     this.dicBuild[num - 3]++;
                    //     this.dicBuild[num - 2] = 0;

                    // }
                    // if (this.dicBuild[num - 2] != 0 && this.dicBuild[num - 2] == this.dicBuild[num - 1]) {
                    //     this.dicBuild[num - 2]++;
                    //     this.dicBuild[num - 1] = 0;

                    // }
                    // if (this.dicBuild[num - 1] != 0 && this.dicBuild[num - 1] == this.dicBuild[num]) {
                    //     this.dicBuild[num - 1]++;
                    //     this.dicBuild[num] = 0;

                    // }


                }
                break;
            case Move.RightUpToLeftDown:
                //  *              1  
                //  *          5       2  
                //  *      9       6       3
                //  *  13      10      7       4
                //  *      14      11      8 
                //  *          15      12    
                //  *              16

                for (let num = 4; num >= 1; num--) {  //横向
                    //循环的目的是消除建筑之间的空白地带  把建筑变紧凑
                    for (let i = num + 8; i >= num; i -= 4) {
                        for (let j = num + 12; j >= num + 4; j -= 4) {
                            if (this.dicBuild[j] == 0 && this.dicBuild[i] != 0) {
                                this.dicBuild[j] = this.dicBuild[i];
                                this.dicBuild[i] = 0;
                                this.singlePosRender(i, this.dicBuild[j], j);
                            }
                        }
                    }
                    // if (this.dicBuild[num + 12] != 0 && this.dicBuild[num + 12] == this.dicBuild[num + 8]) {
                    //     this.dicBuild[num + 12]++;
                    //     this.dicBuild[num + 8] = 0;

                    // } if (this.dicBuild[num + 8] != 0 && this.dicBuild[num + 8] == this.dicBuild[num + 4]) {
                    //     this.dicBuild[num + 8]++;
                    //     this.dicBuild[num + 4] = 0;

                    // } if (this.dicBuild[num + 4] != 0 && this.dicBuild[num + 4] == this.dicBuild[num]) {
                    //     this.dicBuild[num + 4]++;
                    //     this.dicBuild[num] = 0;

                    // }
                }
                break;
        }
        this.randomBuild();
        this.updateScore();
        this.updateBodyValue();
        this.resetMouse();
        // this.posRender();
        if (this.isDead())
            alert("游戏结束");
    }


    /**
     * 建筑从格子移动到另一个格子
     * 
     * @param {number} fromPosVar 移动开始位置变量
     * @param {number} fromBuild  移动开始的位置的建筑
     * @param {number} toPosVar   移动目标点的变量  
     * @memberof map
     */
    singlePosRender(fromPosVar: number, fromBuild: number, toPosVar: number) {
        console.log("单体渲染");
        if (fromBuild == 0) return;
        let pos = this.getPosVar(fromPosVar);

        let skin = this.getSkin(fromBuild);
        //从起始点位置生成一张图片
        let image: Laya.Image = new Laya.Image();
        //输出日志
        console.log("pos: x:%d,y:%d", pos.x, pos.y);
      
        //在point这个位置加载一张新图片
        image.loadImage(skin, pos.x, pos.y, 0, 0);
        //图片加入
        Laya.stage.addChild(image);
        //将原始图片visible关闭
        pos.visible = false;
        //皮肤取消
        pos.skin = "";
        //缓动到新的位置 消失
        let targetPos = this.getPosVar(toPosVar);
        Laya.Tween.to(image, { y: targetPos.y, x: targetPos.x },
            1000, null, Laya.Handler.create(this, this.singlePosRenderComplete, [image, targetPos]), 1000);
    }

    singlePosRenderComplete(image: Laya.Image, target: Laya.Image, skin: string) {

        target.skin = skin;
        target.visible = true;
        //新的位置图片皮肤更改 visible开启

        image.removeSelf();
        image.destroy();
    }

    /**
     * 更新体力值
     * 
     * @memberof map
     */
    updateBodyValue() {
        if (this.bodyValue > 0) {
            this.bodyValue--;
            this.lbl_tili.text = this.bodyValue.toString();

            //TODO 体力不足了 增加体力
            if (this.bodyValue == 0) {
                this.randomDice();
                this.buildMove();
            }
        } else {
            this.buildMove();
            alert("体力不足");
        }
    }

    /**
     * 移动建筑到下方
     * 
     * @memberof map
     */
    buildMove() {
        let pos = 0;
        let buildId = 1;

        for (let key in this.dicBuild) {
            if (this.dicBuild[key] == 0) continue;
            if (this.dicBuild[key] >= buildId) {
                buildId = this.dicBuild[key]
                pos = parseInt(key);
            }
        }

        var posVar = this.getPosVar(pos);

        var image = new Laya.Image();
        image.loadImage(this.getSkin(buildId), 250, 300);
        Laya.stage.addChild(image);
        Laya.Tween.to(image, { y: this.worker.y, x: this.lbl_tili.x },
            600, Laya.Ease.backIn, Laya.Handler.create(this, this.buildMoveComplete, [image]), 800);
    }


    /**
     * 移动回掉
     * 
     * @param {Laya.Image} image 
     * @memberof map
     */
    buildMoveComplete(image: Laya.Image) {
        image.removeSelf();
        image.destroy();
    }

    /**
     * 更新分数
     * 
     * @memberof map
     */
    updateScore() {
        //this.score // 上一局的分数
        let score = 0;
        for (let i = 1; i <= 16; i++) {
            switch (this.dicBuild[i]) {
                case 1: score += 500;
                    break;
                case 2: score += 1000;
                    break;
                case 3: score += 2000;
                    break;
                case 4: score += 4000;
                    break;
                case 5: score += 8000;
                    break;
                case 6: score += 16000;
                    break;
                case 7: score += 32000;
                    break;
                case 8: score += 64000;
                    break;
                case 9: score += 128000;
                    break;
                case 10: score += 256000;
                    break;
                case 11: score += 512000;
                    break;
                case 12: score += 1024000;
                    break;
                case 13: score += 2048000;
                    break;
            }
        }
        this.score = score;
        this.lbl_score.text = this.score.toString();
    }


    /**
     * 死亡判断
     *              1  
     *          5       2  
     *      9       6       3
     *  13      10      7       4
     *      14      11      8 
     *          15      12    
     *              16
     * @memberof map
     */
    isDead() {
        this.gameover = true;
        for (let i = 1; i <= 16; i++) {
            if (this.dicBuild[i] == 0) {
                this.gameover = false;
                break;
            } else {
                if (this.dicBuild[i + 1] && this.dicBuild[i] == this.dicBuild[i + 1]) {
                    if (i % 4 != 0) {
                        this.gameover = false;
                        break;
                    }
                } else if (this.dicBuild[i - 1] && this.dicBuild[i] == this.dicBuild[i - 1]) {
                    if (i % 4 != 1) {
                        this.gameover = false;
                        break;
                    }
                } else if (this.dicBuild[i + 4] && this.dicBuild[i] == this.dicBuild[i + 4]) {
                    this.gameover = false;
                    break;
                } else if (this.dicBuild[i - 4] && this.dicBuild[i] == this.dicBuild[i - 4]) {
                    this.gameover = false;
                    break;
                }
            }
        }
        return this.gameover;
    }


    /**
     * 重置鼠标点
     * 
     * @memberof map
     */
    resetMouse() {
        this.lastTouch.x = 0;
        this.lastTouch.y = 0;
        this.firstTouch.x = 0;
        this.firstTouch.y = 0;
        this.mouseUp = false;
    }

    /**
     * 初始化地图
     * 
     * @memberof map
     */
    init() {
        this.initScore();
        this.setInitPos();
        this.setInitBuild();
        this.posRender();
        this.updateScore();
        this.randomDice();
    }


    /**
     * 扔骰子
     * 
     * @memberof map
     */
    randomDice() {

        this.bodyValue = Tool.Random(1, 7);
        let ani: Laya.FrameAnimation;
        switch (this.bodyValue) {
            case 1: ani = this.ani1;
                this.diceNumber = 1;
                break;
            case 2: ani = this.ani2;
                this.diceNumber = 2;
                break;
            case 3: ani = this.ani3;
                this.diceNumber = 3;
                break;
            case 4: ani = this.ani4;
                this.diceNumber = 4;
                break;
            case 5: ani = this.ani5;
                this.diceNumber = 5;
                break;
            case 6: ani = this.ani6;
                this.diceNumber = 6;
                break;
        }
        ani.on(Laya.Event.COMPLETE, this, this.playDice, [ani]);
        this.imgDice.visible = true;
        ani.play(null, false);
    }

    playDice(ani: Laya.FrameAnimation): void {
        if (ani) {
            ani.stop();
            ani.removeSelf();
            this.imgDice.visible = false;
            let x = 302;
            let y = 257;
            this.diceMove(this.diceNumber, x, y);
        }
    }

    /**
     * 骰子移动动画
     * @param {number} num 
     * @param {number} x 
     * @param {number} y 
     * @memberof map
     */
    diceMove(num: number, x: number, y: number) {
        let image: Laya.Image = new Laya.Image();
        switch (num) {
            case 1: image.loadImage("map/main_bg/shaizi/1-1.png", x, y); break;
            case 2: image.loadImage("map/main_bg/shaizi/2-1.png", x, y); break;
            case 3: image.loadImage("map/main_bg/shaizi/3-1.png", x, y); break;
            case 4: image.loadImage("map/main_bg/shaizi/4-1.png", x, y); break;
            case 5: image.loadImage("map/main_bg/shaizi/5-1.png", x, y); break;
            case 6: image.loadImage("map/main_bg/shaizi/6-1.png", x, y); break;
        }
        Laya.stage.addChild(image);
        Laya.Tween.to(image, { y: this.lbl_tili.y - 16, x: this.lbl_tili.x - 18, scaleX: 0.1, scaleY: 0.1 },
            600, Laya.Ease.linearNone, Laya.Handler.create(this, this.diceMoveComplete, [image]), 800);
    }


    /**
     * 移动完成回调函数
     * 
     * @param {Laya.Image} image 
     * @memberof map
     */
    diceMoveComplete(image: Laya.Image): void {
        image.removeSelf();
        image.destroy();
        this.lbl_tili.text = this.bodyValue.toString();
    }

    /**
     * 初始化分数
     * 
     * @memberof map
     */
    initScore() {
        this.score = 0;
        this.lbl_score.text = this.score.toString();
        this.lbl_tili.text = "0";
    }

    /**
     * 设置初始化2个坐标
     * 
     * @memberof map
     */
    setInitPos() {
        this.initPos = [];
        do {
            let number = Tool.Random(1, 17);
            if (this.initPos.indexOf(number, 0) == -1) {
                this.initPos.push(number);
            }
        } while (this.initPos.length < 2);
    }



    /**
     * 设置初始化的坐标的建筑
     * @memberof map
     */
    setInitBuild() {
        this.dicBuild = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0 };
        for (let i = 0; i < this.initPos.length; i++) {
            this.dicBuild[this.initPos[i]] = Tool.Random(1, 3);
        }
    }

    /**
     * 
     * 随机生成一个格子
     * @memberof map
     */
    randomBuild() {
        let g = false;
        for (let i = 1; i < 17; i++) {
            if (this.dicBuild[i] == 0) {
                g = true;
                break;
            }
        }
        if (g) {
            let b = true;
            do {
                let i = Tool.Random(1, 17);

                if (this.dicBuild[i] == 0) {
                    this.dicBuild[i] = 1;
                    b = false;
                }
            }
            while (b);
        }
    }

    /**
     * 渲染场景
     * 
     * @memberof map
     */
    posRender() {
        console.log("渲染");
        for (let key in this.dicBuild) {
            let pos = this.getPosVar(parseInt(key));
            let build = this.dicBuild[key];
            if (build != 0) {
                let skin = this.getSkin(build);
                pos.skin = skin;
                pos.visible = true;
            } else {
                pos.skin = "";
                pos.visible = false;
            }
        }
        if (this.isDead()) {
            alert("游戏结束");
        }
    }

    getSkin(buildLevel: number) {
        switch (buildLevel) {
            case 1: return "map/main_bg/main_block_1.png";
            case 2: return "map/main_bg/main_block_2.png";
            case 3: return "map/main_bg/main_block_3.png";
            case 4: return "map/main_bg/main_block_4.png";
            case 5: return "map/main_bg/main_block_5.png";
            case 6: return "map/main_bg/main_block_6.png";
            case 7: return "map/main_bg/main_block_7.png";
            case 8: return "map/main_bg/main_block_8.png";
            case 9: return "map/main_bg/main_block_9.png";
            case 10: return "map/main_bg/main_block_10.png";
            case 11: return "map/main_bg/main_block_11.png";
            case 12: return "map/main_bg/main_block_12.png";
            case 13: return "map/main_bg/main_block_13.png";
            default: return '';
        }
    }
    /**
     * 获取坐标的图片的变量名
     * 
     * @param {number} pos 
     * @returns 
     * @memberof map
     */
    getPosVar(pos: number) {
        switch (pos) {
            case 1: return this.pos1;
            case 2: return this.pos2;
            case 3: return this.pos3;
            case 4: return this.pos4;
            case 5: return this.pos5;
            case 6: return this.pos6;
            case 7: return this.pos7;
            case 8: return this.pos8;
            case 9: return this.pos9;
            case 10: return this.pos10;
            case 11: return this.pos11;
            case 12: return this.pos12;
            case 13: return this.pos13;
            case 14: return this.pos14;
            case 15: return this.pos15;
            case 16: return this.pos16;
        }
    }
}
enum Move {
    LeftDownToRightUp,  //左下到右上
    RightDownToLeftUp,  //右下到左上
    RightUpToLeftDown,  //右上到左下
    LeftUpToRightDown,  //左上到右下
}
